<!DOCTYPE html>
<html lang="en">

<head>
	<meta http-equiv="content-type" content="text/html; charset=utf-8">
	<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
	
	<!-- title -->
	
	<title>
	
		垃圾回收机制 | 
	 
	对线面试官
	</title>
	
	<!-- keywords,description -->
	 
		<meta name="description" content="Java一线大厂面试" />
	

	<!-- favicon -->
	
	<link rel="shortcut icon" href="/luffy/favicon.ico">
	


	<!-- search -->
	<script>
		var searchEngine = "https://www.baidu.com/s?wd=";
		if(typeof searchEngine == "undefined" || searchEngine == null || searchEngine == ""){
			searchEngine = "https://www.google.com/search?q=";
		}
		var homeHost = "";
		if(typeof homeHost == "undefined" || homeHost == null || homeHost == ""){
			homeHost = window.location.host;
		}
	</script>


	
<link rel="stylesheet" href="/luffy/css/main.css">

	
<link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/4.7.0/css/font-awesome.min.css">

	
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@9.17.1/build/styles/darcula.min.css">

	
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.css">


	
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script>

	
<script src="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js"></script>

	
<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@9.17.1/build/highlight.min.js"></script>

	
<script src="https://cdn.jsdelivr.net/npm/jquery-pjax@2.0.1/jquery.pjax.min.js"></script>

	
<script src="/luffy/js/main.js"></script>

	
		
<script src="https://cdn.jsdelivr.net/npm/leancloud-storage/dist/av-min.js"></script>

		
<script src="https://cdn.jsdelivr.net/npm/valine@1.3.10/dist/Valine.min.js"></script>

	
	
<meta name="generator" content="Hexo 5.4.0"></head>

<body>
	<script>
var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?3efe99c287df5a1d6f0d02d187e403c1";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();
</script>

<header id="header">
    <a id="title" target="_blank" rel="noopener" href="https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzU4NzA3MTc5Mg==&action=getalbum&album_id=1657204970858872832&scene=126#wechat_redirect" class="logo">对线面试官</a>

	<ul id="menu">
		
	

	

		<li class="menu-item">
			<a href="https://gitee.com/zhongfucheng/Java3y" class="menu-item-link" target="_blank">
				【戳这里】获取更多原创干货💪💪
			</a>
		</li>
		<li class="menu-item">
			<a href="https://gitee.com/zhongfucheng/Java3y" class="menu-item-link" target="_blank">
				<i class="fa fa-github fa-2x"></i>
			</a>
		</li>
	</ul>
</header>

	
<div id="sidebar">
	<button id="sidebar-toggle" class="toggle" ><i class="fa fa-arrow-right " aria-hidden="true"></i></button>
	
	<div id="site-toc">
		<input id="search-input" class="search-input" type="search" placeholder="按回车全站搜索">
		<div id="tree">
			

			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										00-面试前准备
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/10/30/00-%E9%9D%A2%E8%AF%95%E5%89%8D%E5%87%86%E5%A4%87/01.%E7%AE%80%E5%8E%86/">
										01.简历
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										01-Java基础
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/01-Java%E5%9F%BA%E7%A1%80/01.%20%E6%B3%A8%E8%A7%A3/">
										01. 注解
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/01-Java%E5%9F%BA%E7%A1%80/02.%20%E6%B3%9B%E5%9E%8B/">
										02. 泛型
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/01-Java%E5%9F%BA%E7%A1%80/03.%20JavaNIO/">
										03. JavaNIO
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/01-Java%E5%9F%BA%E7%A1%80/04.%20%E5%8F%8D%E5%B0%84%E5%92%8C%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86/">
										04. 反射和动态代理
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										02-Java并发
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/01.%20%E5%A4%9A%E7%BA%BF%E7%A8%8B%E5%9F%BA%E7%A1%80/">
										01. 多线程基础
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/02.%20CAS/">
										02. CAS
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/03.%20synchronized/">
										03. synchronized
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/04.%20AQS%E5%92%8CReentrantLock/">
										04. AQS和ReentrantLock
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/05.%20%E7%BA%BF%E7%A8%8B%E6%B1%A0/">
										05. 线程池
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/06.%20ThreadLocal/">
										06. ThreadLocal
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/07.%20CountDownLatch%E5%92%8CCyclicBarrier/">
										07. CountDownLatch和CyclicBarrier
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/08.%20%E4%B8%BA%E4%BB%80%E4%B9%88%E9%9C%80%E8%A6%81Java%E5%86%85%E5%AD%98%E6%A8%A1%E5%9E%8B/">
										08. 为什么需要Java内存模型
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/09.%20%E6%B7%B1%E5%85%A5%E6%B5%85%E5%87%BAJava%E5%86%85%E5%AD%98%E6%A8%A1%E5%9E%8B/">
										09. 深入浅出Java内存模型
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										03-Java容器
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/03-Java%E5%AE%B9%E5%99%A8/01.%20List%E9%9B%86%E5%90%88/">
										01. List集合
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/03-Java%E5%AE%B9%E5%99%A8/02.%20Map%E9%9B%86%E5%90%88/">
										02. Map集合
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										04-Java虚拟机
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/01.%20Java%E7%BC%96%E8%AF%91%E5%88%B0%E6%89%A7%E8%A1%8C%E7%9A%84%E8%BF%87%E7%A8%8B/">
										01. Java编译到执行的过程
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/02.%20%E5%8F%8C%E4%BA%B2%E5%A7%94%E6%B4%BE%E6%9C%BA%E5%88%B6/">
										02. 双亲委派机制
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/03.%20JVM%E5%86%85%E5%AD%98%E7%BB%93%E6%9E%84/">
										03. JVM内存结构
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file active">
									<a href="/luffy/2021/08/19/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/04.%20%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6%E6%9C%BA%E5%88%B6/">
										04. 垃圾回收机制
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/20/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/05.%20CMS%E5%9E%83%E5%9C%BE%E6%94%B6%E9%9B%86%E5%99%A8/">
										05. CMS垃圾收集器
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/20/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/06.%20G1%E5%9E%83%E5%9C%BE%E6%94%B6%E9%9B%86%E5%99%A8/">
										06. G1垃圾收集器
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/24/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/07.%20JVM%E8%B0%83%E4%BC%98/">
										07. JVM调优
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										05-Spring
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/05-Spring/01.%20SpringMVC/">
										01. SpringMVC
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/05-Spring/02.%20Spring%E5%9F%BA%E7%A1%80/">
										02. Spring基础
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/05-Spring/03.%20SpringBean%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F/">
										03. SpringBean生命周期
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										06-Redis
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/06-Redis/01.%20Redis%E5%9F%BA%E7%A1%80/">
										01. Redis基础
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/06-Redis/02.%20Redis%E6%8C%81%E4%B9%85%E5%8C%96/">
										02. Redis持久化
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/20/06-Redis/03.%20Redis%E4%B8%BB%E4%BB%8E%E6%9E%B6%E6%9E%84/">
										03. Redis主从架构
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/20/06-Redis/04.%20Redis%E5%88%86%E7%89%87%E9%9B%86%E7%BE%A4/">
										04. Redis分片集群
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										07-消息队列
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/07-%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97/01.%20Kafka%E5%9F%BA%E7%A1%80/">
										01. Kafka基础
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/07-%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97/02.%20%E4%BD%BF%E7%94%A8Kafka%E4%BC%9A%E8%80%83%E8%99%91%E4%BB%80%E4%B9%88%E9%97%AE%E9%A2%98/">
										02. 使用Kafka会考虑什么问题
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										08-MySQL
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/08-MySQL/01.%20MySQL%E7%B4%A2%E5%BC%95/">
										01. MySQL索引
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/08-MySQL/02.%20MySQL%E4%BA%8B%E5%8A%A1%E5%92%8C%E9%94%81%E6%9C%BA%E5%88%B6%E5%92%8CMVCC/">
										02. MySQL事务和锁机制和MVCC
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/08-MySQL/03.%20MySQL%E8%B0%83%E4%BC%98/">
										03. MySQL调优
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										09-项目场景类
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/20/09-%E9%A1%B9%E7%9B%AE%E5%9C%BA%E6%99%AF%E7%B1%BB/01.%20%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E5%8E%BB%E9%87%8D%E5%92%8C%E5%B9%82%E7%AD%89/">
										01. 如何实现去重和幂等
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/20/09-%E9%A1%B9%E7%9B%AE%E5%9C%BA%E6%99%AF%E7%B1%BB/02.%20%E7%B3%BB%E7%BB%9F%E9%9C%80%E6%B1%82%E5%A4%9A%E5%8F%98%E5%A6%82%E4%BD%95%E8%AE%BE%E8%AE%A1/">
										02. 系统需求多变如何设计
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/20/09-%E9%A1%B9%E7%9B%AE%E5%9C%BA%E6%99%AF%E7%B1%BB/03.%20%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/">
										03. 设计模式
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										10-计算机网络
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/25/10-%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/01.%20HTTP/">
										01. HTTP
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/10/13/10-%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/02.TCP%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B%E5%92%8C%E5%9B%9B%E6%AC%A1%E6%8C%A5%E6%89%8B/">
										02.TCP三次握手和四次挥手
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										11-算法
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/09/01/11-%E7%AE%97%E6%B3%95/01.%20%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95/">
										01. 排序算法
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/09/02/11-%E7%AE%97%E6%B3%95/02.%20LeetCode%20Easy/">
										02. LeetCode Easy
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/09/02/11-%E7%AE%97%E6%B3%95/02.%20LeetCode%20Medium/">
										02. LeetCode Medium
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										12-austin项目
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/11/01/12-austin%E9%A1%B9%E7%9B%AE/00.%E9%A1%B9%E7%9B%AE%E4%BB%8B%E7%BB%8D/">
										00.项目介绍
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/10/30/12-austin%E9%A1%B9%E7%9B%AE/01.%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA/">
										01.环境搭建
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/10/30/12-austin%E9%A1%B9%E7%9B%AE/02.%E6%97%A5%E5%BF%97/">
										02.日志
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/11/24/12-austin%E9%A1%B9%E7%9B%AE/03.%E5%B7%A5%E5%85%B7%E5%8C%85/">
										03.工具包
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/11/24/12-austin%E9%A1%B9%E7%9B%AE/04.%E4%BB%8E%E4%B8%80%E6%9D%A1%E7%9F%AD%E4%BF%A1%E5%BC%80%E5%A7%8B/">
										04.从一条短信开始
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/11/24/12-austin%E9%A1%B9%E7%9B%AE/05.%E9%80%89%E6%8B%A9%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E6%8A%80%E6%9C%AF%E9%80%89%E5%9E%8B/">
										05.选择数据库和技术选型
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/11/24/12-austin%E9%A1%B9%E7%9B%AE/06.MySQL%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA/">
										06.MySQL环境搭建
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/11/24/12-austin%E9%A1%B9%E7%9B%AE/07.Kafka%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA/">
										07.Kafka环境搭建
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
		</div>
	</div>
</div>

	<!-- 引入正文 -->
	<div id="content">
		<h1 id="article-title">

	04. 垃圾回收机制
</h1>
<div class="article-meta">
	
	<span>3y</span>
	<span>2021-08-19 21:15:57</span>
		<div id="article-categories">
    
		<span>Categories：</span>
            
    

    
		<span>Tags：</span>
            
    
		</div>

</div>

<div id="article-content">
	<p><span style="color:#ab4642"><strong>面试官</strong></span>：我还记得上次你讲到JVM内存结构（运行时数据区域）提到了「堆」，然后你说是分了几块区域嘛</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：当时感觉再讲下去那我可能就得加班了</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：<strong>今天有点空了，继续聊聊「堆」那块吧</strong></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：嗯，前面提到了堆分了「新生代」和「老年代」，「新生代」又分为「Eden」和「Survivor」区，「survivor」区又分为「From Survivor」和「To Survivor」区</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gs8mqqc719j31i00ootj1.jpg"></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：说到这里，我就想聊聊Java的垃圾回收机制了</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：那你开始你的表演吧</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：我们使用Java的时候，会创建很多对象，但我们未曾「手动」将这些对象进行清除</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：而如果用C/C++语言的时候，用完是需要自己free(释放)掉的</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：那为什么在写Java的时候不用我们自己手动释放”垃圾”呢？原因很简单，JVM帮我们做了（自动回收垃圾）</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：嗯…</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：我个人对垃圾的定义：只要对象不再被使用了，那我们就认为该对象就是垃圾，对象所占用的空间就可以被回收</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtvmidk0dxj60yw07kdgv02.jpg"></p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：<strong>那是怎么判断对象不再被使用的呢？</strong></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：常用的算法有两个「引用计数法」和「可达性分析法」</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：引用计数法思路很简单：当对象被引用则+1，但对象引用失败则-1。当计数器为0时，说明对象不再被引用，可以被可回收</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：引用计数法最明显的缺点就是：如果对象存在循环依赖，那就无法定位该对象是否应该被回收（A依赖B，B依赖A）</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：嗯…</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：另一种就是可达性分析法：它从「GC Roots」开始向下搜索，当对象到「GC Roots」都没有任何引用相连时，说明对象是不可用的，可以被回收</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtvmj0i3dnj60r005wgm302.jpg"></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：「GC Roots」是一组必须「活跃」的引用。从「GC Root」出发，程序通过直接引用或者间接引用，能够找到可能正在被使用的对象</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：<strong>还是不太懂，那「GC Roots」一般是什么？你说它是一组活跃的引用，能不能举个例子，太抽象了。</strong></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：比如我们上次不是聊到JVM内存结构中的虚拟机栈吗，虚拟机栈里不是有栈帧吗，栈帧不是有局部变量吗？局部变量不就存储着引用嘛。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：那如果栈帧位于虚拟机栈的栈顶，是不是就可以说明这个栈帧是活跃的（换言之，是线程正在被调用的）</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：既然是线程正在调用的，那栈帧里的指向「堆」的对象引用，是不是一定是「活跃」的引用？</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：所以，当前活跃的栈帧指向堆里的对象引用就可以是「GC Roots」</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：嗯…</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：当然了，能作为「GC Roots」也不单单只有上面那一小块</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：比如类的静态变量引用是「GC Roots」，被「Java本地方法」所引用的对象也是「GC Roots」等等…</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtvmju1matj60wm078gml02.jpg"></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：回到理解的重点：「GC Roots」是一组必须「活跃」的「引用」，只要跟「GC Roots」没有直接或者间接引用相连，那就是垃圾</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：JVM用的就是「可达性分析算法」来判断对象是否垃圾</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：懂了</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：垃圾回收的第一步就是「标记」，标记哪些没有被「GC Roots」引用的对象</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gsangi5eucj31150u0tg6.jpg"></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：标记完之后，我们就可以选择直接「清除」，只要不被「GC Roots」关联的，都可以干掉</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：过程非常简单粗暴，但也存在很明显的问题</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：直接清除会有「内存碎片」的问题：可能我有10M的空余内存，但程序申请9M内存空间却申请不下来（10M的内存空间是垃圾清除后的，不连续的）</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gsannpsdmrj31ve0skthm.jpg"></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：那解决「内存碎片」的问题也比较简单粗暴，「标记」完，不直接「清除」。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：我把「标记」存活的对象「复制」到另一块空间，复制完了之后，直接把原有的整块空间给干掉！这样就没有内存碎片的问题了</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：这种做法缺点又很明显：内存利用率低，得有一块新的区域给我复制(移动)过去</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：嗯…</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：还有一种「折中」的办法，我未必要有一块「大的完整空间」才能解决内存碎片的问题，我只要能在「当前区域」内进行移动</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：把存活的对象移到一边，把垃圾移到一边，那再将垃圾一起删除掉，不就没有内存碎片了嘛</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：这种专业的术语就叫做「整理」</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gsaq5q3ci6j31um0s612x.jpg"></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：扯了这么久，我们把思维再次回到「堆」中吧</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：经过研究表明：大部分对象的生命周期都很短，而只有少部分对象可能会存活很长时间</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：又由于「垃圾回收」是会导致「stop the world」（应用停止访问）</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：理解「stop the world」应该很简单吧：回收垃圾的时候，程序是有短暂的时间不能正常继续运作啊。不然JVM在回收的时候，用户线程还继续分配修改引用，JVM怎么搞（：</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：为了使「stop the world」持续的时间尽可能短以及提高并发式GC所能应付的内存分配速率</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：在很多的垃圾收集器上都会在「物理」或者「逻辑」上，把这两类对象进行区分，死得快的对象所占的区域叫做「年轻代」，活得久的对象所占的区域叫做「老年代」</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtvmladwfgj60wy0lmq6f02.jpg"></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：但也不是所有的「垃圾收集器」都会有，只不过我们现在线上用的可能都是JDK8，JDK8及以下所使用到的垃圾收集器都是有「分代」概念的。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：所以，你可以看到我的「堆」是画了「年轻代」和「老年代」</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：要值得注意的是，高版本所使用的垃圾收集器的ZGC是没有分代的概念的（：</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：只不过我为了好说明现状，ZGC的话有空我们再聊</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：嗯…好吧</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：在前面更前面提到了垃圾回收的过程，其实就对应着几种「垃圾回收算法」，分别是：</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：标记清除算法、标记复制算法和标记整理算法【「标记」「清除」「复制」「整理」】</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：经过上面的铺垫之后，这几种算法应该还是比较好理解的</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtvmmnlrf9j612u06aq3w02.jpg"></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：「分代」和「垃圾回收算法」都搞明白了之后，我们就可以看下在JDK8生产环境及以下常见的垃圾回收器了</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：「年轻代」的垃圾收集器有：Seria、Parallel Scavenge、ParNew</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：「老年代」的垃圾收集器有：Serial Old、Parallel Old、CMS</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：看着垃圾收集器有很多，其实还是非常好理解的。Serial是单线程的，Parallel是多线程</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：这些垃圾收集器实际上就是「实现了」垃圾回收算法（标记复制、标记整理以及标记清除算法）</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：CMS是「JDK8之前」是比较新的垃圾收集器，它的特点是能够尽可能减少「stop the world」时间。在垃圾回收时让用户线程和 GC 线程能够并发执行！</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtvofmvvfjj611q0de40c02.jpg"></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：又可以发现的是，「年轻代」的垃圾收集器使用的都是「标记复制算法」</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：所以在「堆内存」划分中，将年轻代划分出Survivor区（Survivor From 和Survivor To），目的就是为了有一块完整的内存空间供垃圾回收器进行拷贝(移动)</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：而新的对象则放入Eden区</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：我下面重新画下「堆内存」的图，因为它们的大小是有默认的比例的</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gsiu2piom2j31nd0u0aob.jpg"></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：图我已经画好了，应该就不用我再说明了</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：<strong>我还想问问，就是，新创建的对象一般是在「新生代」嘛，那在什么时候会到「老年代」中呢？</strong></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：嗯，我认为简单可以分为两种情况：</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：1. 如果对象太大了，就会直接进入老年代（对象创建时就很大 ||  Survivor区没办法存下该对象）</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：2. 如果对象太老了，那就会晋升至老年代（每发生一次Minor GC ，存活的对象年龄+1，达到默认值15则晋升老年代 || 动态对象年龄判定 可以进入老年代）</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtvoks5xcgj60l10h9q3d02.jpg"></p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：<strong>既然你又提到了Minor GC，那Minor GC 什么时候会触发呢？</strong></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：当Eden区空间不足时，就会触发Minor GC</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：Minor GC 在我的理解就是「年轻代」的GC，你前面又提到了「GC Roots」嘛</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：<strong>那在「年轻代」GC的时候，从GC Roots出发，那不也会扫描到「老年代」的对象吗？那那那..不就相当于全堆扫描吗？</strong></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：这JVM里也有解决办法的。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：HotSpot 虚拟机「老的GC」（G1以下）是要求整个GC堆在连续的地址空间上。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：所以会有一条分界线（一侧是老年代，另一侧是年轻代），所以可以通过「地址」就可以判断对象在哪个分代上</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：当做Minor GC的时候，从GC Roots出发，如果发现「老年代」的对象，那就不往下走了（Minor GC对老年代的区域毫无兴趣）</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtvooynl3xj60rg070abg02.jpg"></p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：<strong>但又有个问题，那如果「年轻代」的对象被「老年代」引用了呢？（老年代对象持有年轻代对象的引用），那时候肯定是不能回收掉「年轻代」的对象的</strong>。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：HotSpot虚拟机下 有「card table」（卡表）来避免全局扫描「老年代」对象</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：「堆内存」的每一小块区域形成「卡页」，卡表实际上就是卡页的集合。当判断一个卡页中有存在对象的跨代引用时，将这个页标记为「脏页」</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：那知道了「卡表」之后，就很好办了。每次Minor GC 的时候只需要去「卡表」找到「脏页」，找到后加入至GC Root，而不用去遍历整个「老年代」的对象了。</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtvoodyjk6j60uu09gq4q02.jpg"></p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：嗯嗯嗯，还可以的啊，要不继续聊聊CMS？</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：这面试快一个小时了吧，我图也画了这么多了。下次？下次吧？有点儿累了</p>
<p><strong>本文总结</strong>：</p>
<ul>
<li><p><strong>什么是垃圾</strong>：只要对象不再被使用，那即是垃圾</p>
</li>
<li><p><strong>如何判断为垃圾</strong>：可达性分析算法和引用计算算法，JVM使用的是可达性分析算法</p>
</li>
<li><p><strong>什么是GC Roots</strong>：GC Roots是一组必须活跃的引用，跟GC Roots无关联的引用即是垃圾，可被回收</p>
</li>
<li><p><strong>常见的垃圾回收算法</strong>：标记清除、标记复制、标记整理</p>
</li>
<li><p><strong>为什么需要分代</strong>：大部分对象都死得早，只有少部分对象会存活很长时间。在堆内存上都会在物理或逻辑上进行分代，为了使「stop the world」持续的时间尽可能短以及提高并发式GC所能应付的内存分配速率。</p>
</li>
<li><p><strong>Minor GC</strong>：当Eden区满了则触发，从GC Roots往下遍历，年轻代GC不关心老年代对象</p>
</li>
<li><p><strong>什么是card table</strong>【卡表】：空间换时间（类似bitmap），能够避免扫描老年代的所有对应进而顺利进行Minor GC （案例：老年代对象持有年轻代对象引用）</p>
</li>
<li><p><strong>堆内存占比</strong>：年轻代占堆内存1/3，老年代占堆内存2/3。Eden区占年轻代8/10，Survivor区占年轻代2/10（其中From 和To 各站1/10)</p>
</li>
</ul>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtmf49rbzoj61400mijt902.jpg"></p>
<p><span align="center">第一时间获取<span style="color:#000080"><strong>BATJTMD一线互联网大厂</strong></span>最新的面试资料以及内推机会关注公众号<span style="color:#ab4642"><strong>「对线<span style="color:#ab4642"></strong><span style="color:#ab4642"><strong>面试官</strong></span><strong></span>」</strong></span></p>
<img align="center" src='https://tva1.sinaimg.cn/large/008i3skNgy1gtlvty8zo5j60u00u0q5602.jpg' width=300px height=300px />


</div>


    <div class="post-guide">
        <div class="item left">
            
              <a href="/luffy/2021/08/20/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/05.%20CMS%E5%9E%83%E5%9C%BE%E6%94%B6%E9%9B%86%E5%99%A8/">
                  <i class="fa fa-angle-left" aria-hidden="true"></i>
                  05. CMS垃圾收集器
              </a>
            
        </div>
        <div class="item right">
            
              <a href="/luffy/2021/08/19/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/03.%20JVM%E5%86%85%E5%AD%98%E7%BB%93%E6%9E%84/">
                03. JVM内存结构
                <i class="fa fa-angle-right" aria-hidden="true"></i>
              </a>
            
        </div>
    </div>




<script>
	
	
</script>
	</div>
	<button id="totop-toggle" class="toggle"><i class="fa fa-angle-double-up" aria-hidden="true"></i></button>
</body>
</html>
